﻿using System;
using System.Web;

namespace Quail
{
    /// <summary>
    /// Allows access to the cookies on the browser
    /// </summary>
    public class WebCookie : IWebCookie
    {
        /// <summary>
        /// Initializes a new instance of the WebCookie class.
        /// </summary>
        /// <param name="browser">The browser for the cookies</param>
        public WebCookie(WebBrowser browser)
        {
            Browser = browser;
        }

        /// <summary>
        /// Gets or sets the Browser
        /// </summary>
        private WebBrowser Browser
        {
            get; set;
        }

        /// <summary>
        /// Returns the cookies on the current page
        /// </summary>
        /// <returns>A cookie collection</returns>
        public HttpCookieCollection GetCookies()
        {
            var task = Browser.TestSession.RootTask.BeginTask("WebCookie.GetCookies");
            try
            {
                var result = GetCookiesFromString(Browser.SeleniumInterface.GetCookie());
                task.Finish();
                return result;
            }
            catch (Exception e)
            {
                task.Finish(e);
                throw;
            }
        }

        /// <summary>
        /// Checks to see if a cookie is present
        /// </summary>
        /// <param name="name">Name of the cookie</param>
        /// <returns>True if the cookie exists</returns>
        public bool DoesCookieExist(string name)
        {
            var task = Browser.ActiveTask.BeginTask("DoesCookieExist");
            task.AddAttribute("CookieName", name);
            try
            {
                var result = Browser.SeleniumInterface.IsCookiePresent(name); 
                task.Finish(result.ToString());
                return result;
            }
            catch (Exception e)
            {
                task.Finish(e);
                throw;
            }
        }

        /// <summary>
        /// Returns a cookie's value
        /// </summary>
        /// <param name="name">Name of the cookie</param>
        /// <returns>The cookie value</returns>
        public string GetCookieValue(string name)
        {
            var task = Browser.ActiveTask.BeginTask("GetCookieValue");
            task.AddAttribute("CookieName", name);
            try
            {
                var value = Browser.SeleniumInterface.GetCookieByName(name);
                task.Finish(value);
                return value;
            }
            catch (Exception ex)
            {
                task.Finish(ex);
                throw;
            }
        }

        /// <summary>
        /// Attempts to delete a cookie
        /// </summary>
        /// <param name="name">name of the cookie to delete</param>
        public void DeleteCookie(string name)
        {
            var task = Browser.ActiveTask.BeginTask("DeleteCookie");
            task.AddAttribute("CookieName", name);
            try
            {
                Browser.SeleniumInterface.DeleteCookie(name, string.Empty);
                task.Finish();
            }
            catch (Exception ex)
            {
                task.Finish(ex);
                throw;
            }
        }

        public static HttpCookieCollection GetCookiesFromString(string s)
        {
            var result = new HttpCookieCollection();

            foreach (var namevaluepairT in s.Split(';'))
            {
                var namevaluepair = namevaluepairT.Trim();
                var namevalue = namevaluepair.Trim().Split('=');

                if (namevalue.Length == 2)
                {
                    result.Add(new HttpCookie(namevalue[0], HttpUtility.UrlDecode(namevalue[1])));
                }
                else
                {
                    // we have some nested cookies
                    var cookie = new HttpCookie(namevalue[0]);

                    foreach (var subnamevaluepairT in namevaluepair.Substring(namevaluepair.IndexOf('=') + 1).Split('&'))
                    {
                        var subnamevaluepair = subnamevaluepairT.Trim();
                        var equalidx = subnamevaluepair.IndexOf('=');

                        if (equalidx > 0)
                        {
                            cookie.Values.Add(
                                subnamevaluepair.Substring(0, equalidx),
                                subnamevaluepair.Substring(equalidx + 1));
                        }
                    }
                }
            }

            return result;
        }
    }
}
